Communication between clients occurs through ``channels'' that can be created, joined and locked. Each channel has a unique name (simply a string) that identifies that channel, which can then be used as an argument in messages to denote that the target for message is that particular channel. A new channel is created upon joining an empty channel, which also means that a channel is destroyed when there are no longer any users in that channel. Once a client has joined a channel they send messages to that channel and any message sent into that channel by another user will be relayed to them.

Channels can also be locked by any user in that channel. Locking a channel prevents any user from joining that channel who has not been invited by a user already in that channel. Once invited, a user may freely join that channel and send messages as normal but if they leave they must once again be invited in order to join.

The decision to use this architecture was made in order to simplify server design and implementation later on in the project, at the expense of making the client more complex. Rather than making a distinction between group conversations and private conversations, the server can unify all conversations into one reusable component, and instead make the client deal with private conversations through the channel locking mechanism.